#include <windows.h>
#include <string>
#include <sstream>
#include <pdh.h>
#include <pdhmsg.h>
#include <psapi.h>
#include <d3d11.h>
#include <dxgi.h>
#include <vector>
#include <memory>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <shellapi.h>

#pragma comment(lib, "pdh.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "shell32.lib")

// Forward declarations
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DetailWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

// Global variables
HWND g_hwnd = NULL;
HWND g_detailWindow = NULL;  // Handle for the detail window
bool g_bDragging = false;
POINT g_ptDragStart;
bool g_bHidden = false;
std::atomic<bool> g_bRunning(true);
std::mutex g_mutex;
std::condition_variable g_cv;
int g_fontSize = 20;  // Default font size
int g_opacity = 200;  // Default opacity (0-255)
int g_windowWidth = 200;  // Default window width
int g_windowHeight = 100; // Default window height
bool g_bResizing = false;
RECT g_rcResizeStart;
POINT g_ptResizeStart;
bool g_bAutoScaleFont = true;  // 自动缩放字体
bool g_bMouseTracking = false; // Flag to track if mouse tracking is active

// Detail view mode
enum DetailViewMode {
    NONE,
    CPU_DETAILS,
    GPU_DETAILS,
    DISK_DETAILS
};

DetailViewMode g_detailViewMode = NONE;

// Define clickable areas for each component
RECT g_cpuRect = {0};
RECT g_ramRect = {0};
RECT g_gpuRect = {0};
RECT g_diskRect = {0};

// Resize area width
const int RESIZE_AREA_SIZE = 10;

// CPU core information
struct CPUCoreInfo {
    double usage;
};

// GPU information
struct GPUInfo {
    std::wstring name;
    double usage;
    double temperature;
};

// Disk information
struct DiskInfo {
    std::wstring driveLetter;
    double usage;         // Disk activity percentage
    double readRate;      // MB/s
    double writeRate;     // MB/s
    ULONGLONG totalSpace; // Bytes
    ULONGLONG freeSpace;  // Bytes
};

// System metrics
struct SystemMetrics {
    double cpuUsage;
    double memoryUsage;
    double gpuUsage;
    double cpuTemp;
    double gpuTemp;
    double diskUsage;
    std::vector<CPUCoreInfo> cpuCores;
    std::vector<GPUInfo> gpus;
    std::vector<DiskInfo> disks;
};

SystemMetrics g_metrics = {0};

// PDH query for CPU usage
PDH_HQUERY cpuQuery;
PDH_HCOUNTER cpuTotal;
std::vector<PDH_HCOUNTER> cpuCoreCounters;

// PDH query for disk usage
PDH_HQUERY diskQuery;
std::vector<PDH_HCOUNTER> diskCounters;
std::vector<std::wstring> diskNames;

// Function to initialize PDH counters
bool InitPDH() {
    // Initialize CPU counters
    PdhOpenQuery(NULL, NULL, &cpuQuery);
    PdhAddEnglishCounter(cpuQuery, "\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal);
    
    // Get number of CPU cores
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    int numCores = sysInfo.dwNumberOfProcessors;
    
    // Initialize CPU core counters
    g_metrics.cpuCores.resize(numCores);
    cpuCoreCounters.resize(numCores);
    
    for (int i = 0; i < numCores; i++) {
        std::wstring counterPath = L"\\Processor(" + std::to_wstring(i) + L")\\% Processor Time";
        PdhAddEnglishCounterW(cpuQuery, counterPath.c_str(), NULL, &cpuCoreCounters[i]);
    }
    
    // Initialize disk counters
    PdhOpenQuery(NULL, NULL, &diskQuery);
    
    // Get available disk drives
    wchar_t drives[256];
    if (GetLogicalDriveStringsW(256, drives)) {
        wchar_t* drive = drives;
        while (*drive) {
            // Only consider fixed drives
            if (GetDriveTypeW(drive) == DRIVE_FIXED) {
                std::wstring driveLetter = drive;
                // Remove trailing backslash if present
                if (driveLetter.back() == L'\\') {
                    driveLetter.pop_back();
                }
                
                // Add disk to metrics
                DiskInfo diskInfo;
                diskInfo.driveLetter = driveLetter;
                g_metrics.disks.push_back(diskInfo);
                
                // Add disk counter
                std::wstring counterPath = L"\\PhysicalDisk(_Total)\\% Disk Time";
                PDH_HCOUNTER counter;
                PdhAddEnglishCounterW(diskQuery, counterPath.c_str(), NULL, &counter);
                diskCounters.push_back(counter);
                diskNames.push_back(driveLetter);
            }
            // Move to next drive
            drive += wcslen(drive) + 1;
        }
    }
    
    // Collect initial data
    PdhCollectQueryData(cpuQuery);
    PdhCollectQueryData(diskQuery);
    
    return true;
}

// Function to get CPU usage
double GetCPUUsage() {
    PDH_FMT_COUNTERVALUE counterVal;
    PdhCollectQueryData(cpuQuery);
    PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);
    
    // Update CPU core usage
    for (size_t i = 0; i < cpuCoreCounters.size(); i++) {
        PDH_FMT_COUNTERVALUE coreVal;
        PdhGetFormattedCounterValue(cpuCoreCounters[i], PDH_FMT_DOUBLE, NULL, &coreVal);
        g_metrics.cpuCores[i].usage = coreVal.doubleValue;
    }
    
    return counterVal.doubleValue;
}

// Function to get memory usage
double GetMemoryUsage() {
    MEMORYSTATUSEX memInfo;
    memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    GlobalMemoryStatusEx(&memInfo);
    return memInfo.dwMemoryLoad;
}

// Function to get CPU temperature
double GetCPUTemperature() {
    // Getting CPU temperature requires hardware-specific APIs
    // This is a simplified implementation
    // In a real application, you'd use libraries like OpenHardwareMonitor or similar
    
    // For demonstration, we'll return a dummy value
    // In a real application, you'd implement proper temperature monitoring
    static double dummyCpuTemp = 45.0;
    dummyCpuTemp += (rand() % 4 - 2) * 0.1;
    if (dummyCpuTemp < 30) dummyCpuTemp = 30;
    if (dummyCpuTemp > 90) dummyCpuTemp = 90;
    return dummyCpuTemp;
}

// Function to get GPU temperature
double GetGPUTemperature() {
    // Getting GPU temperature requires hardware-specific APIs
    // This is a simplified implementation
    // In a real application, you'd use libraries like OpenHardwareMonitor or similar
    
    // For demonstration, we'll return a dummy value
    // In a real application, you'd implement proper temperature monitoring
    static double dummyGpuTemp = 60.0;
    dummyGpuTemp += (rand() % 4 - 2) * 0.1;
    if (dummyGpuTemp < 40) dummyGpuTemp = 40;
    if (dummyGpuTemp > 95) dummyGpuTemp = 95;
    return dummyGpuTemp;
}

// Function to get GPU usage
double GetGPUUsage() {
    // This is a simplified implementation
    // For a more accurate GPU usage, you would need to use NVIDIA/AMD specific APIs
    // or use Windows Performance Counters for GPU
    
    // For demonstration, we'll return a dummy value
    // In a real application, you'd implement proper GPU monitoring
    static double dummyGpuUsage = 30.0;
    dummyGpuUsage += (rand() % 10 - 5);
    if (dummyGpuUsage < 0) dummyGpuUsage = 0;
    if (dummyGpuUsage > 100) dummyGpuUsage = 100;
    
    // Initialize GPU info if not done yet
    if (g_metrics.gpus.empty()) {
        GPUInfo gpu;
        gpu.name = L"GPU 0";
        gpu.usage = dummyGpuUsage;
        gpu.temperature = GetGPUTemperature();
        g_metrics.gpus.push_back(gpu);
    } else {
        g_metrics.gpus[0].usage = dummyGpuUsage;
        g_metrics.gpus[0].temperature = GetGPUTemperature();
    }
    
    return dummyGpuUsage;
}

// Function to get disk usage
double GetDiskUsage() {
    double totalDiskUsage = 0.0;
    
    // Collect disk data
    PdhCollectQueryData(diskQuery);
    
    // Update disk information
    for (size_t i = 0; i < diskCounters.size() && i < g_metrics.disks.size(); i++) {
        PDH_FMT_COUNTERVALUE counterVal;
        PdhGetFormattedCounterValue(diskCounters[i], PDH_FMT_DOUBLE, NULL, &counterVal);
        
        g_metrics.disks[i].usage = counterVal.doubleValue;
        
        // Get disk space information
        ULARGE_INTEGER freeBytesAvailable, totalBytes, totalFreeBytes;
        std::wstring drivePath = g_metrics.disks[i].driveLetter + L"\\";
        
        if (GetDiskFreeSpaceExW(drivePath.c_str(), &freeBytesAvailable, &totalBytes, &totalFreeBytes)) {
            g_metrics.disks[i].totalSpace = totalBytes.QuadPart;
            g_metrics.disks[i].freeSpace = freeBytesAvailable.QuadPart;
        }
        
        // Dummy read/write rates for demonstration
        // In a real application, you'd track actual I/O rates
        g_metrics.disks[i].readRate = (rand() % 50) * 0.1;
        g_metrics.disks[i].writeRate = (rand() % 30) * 0.1;
        
        totalDiskUsage += g_metrics.disks[i].usage;
    }
    
    // Average disk usage across all disks
    if (!g_metrics.disks.empty()) {
        totalDiskUsage /= g_metrics.disks.size();
    }
    
    return totalDiskUsage;
}

// Function to calculate scaled font size based on window dimensions
int GetScaledFontSize() {
    if (!g_bAutoScaleFont) {
        return g_fontSize;
    }
    
    // Calculate font size based on window dimensions
    // Base size is g_fontSize at 200x100 window
    int baseWidth = 200;
    int baseHeight = 100;
    
    // Calculate scaling factor (average of width and height scaling)
    double widthScale = static_cast<double>(g_windowWidth) / baseWidth;
    double heightScale = static_cast<double>(g_windowHeight) / baseHeight;
    double scaleFactor = (widthScale + heightScale) / 2.0;
    
    // Scale font size with some constraints
    int scaledSize = static_cast<int>(g_fontSize * scaleFactor);
    
    // Set minimum and maximum font size
    if (scaledSize < 12) scaledSize = 12;
    if (scaledSize > 48) scaledSize = 48;
    
    return scaledSize;
}

// Thread function to update system metrics
void UpdateMetricsThread() {
    while (g_bRunning) {
        {
            std::lock_guard<std::mutex> lock(g_mutex);
            g_metrics.cpuUsage = GetCPUUsage();
            g_metrics.memoryUsage = GetMemoryUsage();
            g_metrics.gpuUsage = GetGPUUsage();
            g_metrics.cpuTemp = GetCPUTemperature();
            g_metrics.gpuTemp = GetGPUTemperature();
            g_metrics.diskUsage = GetDiskUsage();
        }
        
        // Notify main thread to update UI
        g_cv.notify_one();
        
        // Update every second
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

// Update window opacity
void UpdateWindowOpacity() {
    SetLayeredWindowAttributes(g_hwnd, 0, g_opacity, LWA_ALPHA);
    if (g_detailWindow) {
        SetLayeredWindowAttributes(g_detailWindow, 0, g_opacity, LWA_ALPHA);
    }
}

// Update window size
void UpdateWindowSize() {
    SetWindowPos(g_hwnd, NULL, 0, 0, g_windowWidth, g_windowHeight, SWP_NOMOVE | SWP_NOZORDER);
}

// Check if mouse is in resize area
bool IsInResizeArea(int x, int y) {
    RECT rc;
    GetClientRect(g_hwnd, &rc);
    
    // Bottom-right corner resize area
    return (x >= rc.right - RESIZE_AREA_SIZE && y >= rc.bottom - RESIZE_AREA_SIZE);
}

// Check if point is within a rectangle
bool IsPointInRect(int x, int y, const RECT& rect) {
    return (x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom);
}

// Format detailed information based on the detail view mode
std::wstring FormatDetailedInfo(DetailViewMode mode) {
    std::wstringstream ss;
    
    std::lock_guard<std::mutex> lock(g_mutex);
    
    if (mode == CPU_DETAILS) {
        // CPU detailed view
        ss << L"CPU Details:" << std::endl;
        ss << L"Total: " << static_cast<int>(g_metrics.cpuUsage) << L"% (" << static_cast<int>(g_metrics.cpuTemp) << L"\u00B0C)" << std::endl;
        
        for (size_t i = 0; i < g_metrics.cpuCores.size(); i++) {
            ss << L"Core " << i << L": " << static_cast<int>(g_metrics.cpuCores[i].usage) << L"%" << std::endl;
        }
    } else if (mode == GPU_DETAILS) {
        // GPU detailed view
        ss << L"GPU Details:" << std::endl;
        
        for (size_t i = 0; i < g_metrics.gpus.size(); i++) {
            ss << g_metrics.gpus[i].name << L": " << static_cast<int>(g_metrics.gpus[i].usage) 
               << L"% (" << static_cast<int>(g_metrics.gpus[i].temperature) << L"\u00B0C)" << std::endl;
        }
    } else if (mode == DISK_DETAILS) {
        // Disk detailed view
        ss << L"Disk Details:" << std::endl;
        
        for (size_t i = 0; i < g_metrics.disks.size(); i++) {
            const auto& disk = g_metrics.disks[i];
            double usedSpaceGB = (disk.totalSpace - disk.freeSpace) / (1024.0 * 1024.0 * 1024.0);
            double totalSpaceGB = disk.totalSpace / (1024.0 * 1024.0 * 1024.0);
            double usedPercent = 100.0 * (1.0 - static_cast<double>(disk.freeSpace) / disk.totalSpace);
            
            ss << disk.driveLetter << L": " << static_cast<int>(disk.usage) << L"% active" << std::endl;
            ss << L"  Space: " << static_cast<int>(usedSpaceGB) << L"/" << static_cast<int>(totalSpaceGB) 
               << L"GB (" << static_cast<int>(usedPercent) << L"%)" << std::endl;
            ss << L"  R/W: " << disk.readRate << L"/" << disk.writeRate << L" MB/s" << std::endl;
        }
    }
    
    return ss.str();
}

// Calculate size needed for detail window based on content
SIZE CalculateDetailWindowSize(const std::wstring& text, int fontSize) {
    // Create a temporary DC
    HDC hdc = GetDC(NULL);
    
    // Create font
    HFONT hFont = CreateFont(fontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
                           DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,
                           CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Segoe UI"));
    HFONT oldFont = (HFONT)SelectObject(hdc, hFont);
    
    // Calculate text dimensions
    RECT rect = {0, 0, 0, 0};
    DrawTextW(hdc, text.c_str(), -1, &rect, DT_CALCRECT);
    
    // Clean up
    SelectObject(hdc, oldFont);
    DeleteObject(hFont);
    ReleaseDC(NULL, hdc);
    
    // Add some padding
    SIZE size;
    size.cx = rect.right - rect.left + 40;  // 20px padding on each side
    size.cy = rect.bottom - rect.top + 40;  // 20px padding on each side
    
    // Ensure minimum size
    if (size.cx < 200) size.cx = 200;
    if (size.cy < 100) size.cy = 100;
    
    return size;
}

// Show detail window
void ShowDetailWindow(DetailViewMode mode, int x, int y) {
    // Close existing detail window if any
    if (g_detailWindow) {
        DestroyWindow(g_detailWindow);
        g_detailWindow = NULL;
    }
    
    // Store the detail view mode
    g_detailViewMode = mode;
    
    if (mode == NONE) {
        return;
    }
    
    // Format the detailed information
    std::wstring detailText = FormatDetailedInfo(mode);
    
    // Register window class for detail window if not already registered
    static bool detailClassRegistered = false;
    if (!detailClassRegistered) {
        WNDCLASSEX wcex = {0};
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = DetailWndProc;
        wcex.hInstance = GetModuleHandle(NULL);
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.lpszClassName = "SystemMonitorDetailClass";
        
        if (!RegisterClassEx(&wcex)) {
            MessageBox(NULL, "Detail Window Registration Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
            return;
        }
        
        detailClassRegistered = true;
    }
    
    // Calculate window size based on content
    SIZE windowSize = CalculateDetailWindowSize(detailText, g_fontSize);
    
    // Create detail window
    g_detailWindow = CreateWindowEx(
        WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE, // Extended window style
        "SystemMonitorDetailClass",                       // Window class
        "Detail View",                                    // Window title
        WS_POPUP,                                         // Window style
        x, y,                                             // Position (will be adjusted)
        windowSize.cx, windowSize.cy,                     // Size
        NULL, NULL, GetModuleHandle(NULL), NULL
    );
    
    if (!g_detailWindow) {
        MessageBox(NULL, "Detail Window Creation Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
        return;
    }
    
    // Store the detail text as window data
    SetPropW(g_detailWindow, L"DetailText", (HANDLE)new std::wstring(detailText));
    
    // Set window transparency
    SetLayeredWindowAttributes(g_detailWindow, 0, g_opacity, LWA_ALPHA);
    
    // Show window
    ShowWindow(g_detailWindow, SW_SHOW);
    UpdateWindow(g_detailWindow);
}

// Detail window procedure
LRESULT CALLBACK DetailWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            
            // Get client area
            RECT rc;
            GetClientRect(hwnd, &rc);
            
            // Create memory DC for double buffering
            HDC memDC = CreateCompatibleDC(hdc);
            HBITMAP memBitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
            HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
            
            // Fill background with semi-transparent black
            HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0));
            FillRect(memDC, &rc, hBrush);
            DeleteObject(hBrush);
            
            // Set text color to white
            SetTextColor(memDC, RGB(255, 255, 255));
            SetBkMode(memDC, TRANSPARENT);
            
            // Create font
            HFONT hFont = CreateFont(g_fontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
                                   DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,
                                   CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Segoe UI"));
            HFONT oldFont = (HFONT)SelectObject(memDC, hFont);
            
            // Get the detail text
            std::wstring* pDetailText = (std::wstring*)GetPropW(hwnd, L"DetailText");
            if (pDetailText) {
                // Draw text
                RECT textRect = rc;
                textRect.left += 20;
                textRect.top += 20;
                DrawTextW(memDC, pDetailText->c_str(), -1, &textRect, DT_NOCLIP);
            }
            
            // Copy from memory DC to screen DC
            BitBlt(hdc, 0, 0, rc.right, rc.bottom, memDC, 0, 0, SRCCOPY);
            
            // Clean up
            SelectObject(memDC, oldFont);
            DeleteObject(hFont);
            SelectObject(memDC, oldBitmap);
            DeleteObject(memBitmap);
            DeleteDC(memDC);
            
            EndPaint(hwnd, &ps);
            return 0;
        }
            
        case WM_DESTROY: {
            // Clean up the detail text
            std::wstring* pDetailText = (std::wstring*)GetPropW(hwnd, L"DetailText");
            if (pDetailText) {
                delete pDetailText;
                RemovePropW(hwnd, L"DetailText");
            }
            
            g_detailWindow = NULL;
            g_detailViewMode = NONE;
            return 0;
        }
            
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

// Window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
        case WM_CREATE: {
            // Initialize PDH
            InitPDH();
            
            // Create system tray icon
            NOTIFYICONDATA nid = {0};
            nid.cbSize = sizeof(NOTIFYICONDATA);
            nid.hWnd = hwnd;
            nid.uID = 1;
            nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
            nid.uCallbackMessage = WM_USER + 1;
            nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
            strcpy_s(nid.szTip, "System Monitor");
            Shell_NotifyIcon(NIM_ADD, &nid);
            
            // Start metrics update thread
            std::thread(UpdateMetricsThread).detach();
            
            return 0;
        }
            
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            
            // Get client area
            RECT rc;
            GetClientRect(hwnd, &rc);
            
            // Create memory DC for double buffering
            HDC memDC = CreateCompatibleDC(hdc);
            HBITMAP memBitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
            HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
            
            // Fill background with semi-transparent black
            HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0));
            FillRect(memDC, &rc, hBrush);
            DeleteObject(hBrush);
            
            // Set text color to white
            SetTextColor(memDC, RGB(255, 255, 255));
            SetBkMode(memDC, TRANSPARENT);
            
            // Create font with adjustable size
            int scaledFontSize = GetScaledFontSize();
            HFONT hFont = CreateFont(scaledFontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
                                    DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,
                                    CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Segoe UI"));
            HFONT oldFont = (HFONT)SelectObject(memDC, hFont);
            
            // Format and draw text
            std::wstringstream ss;
            {
                std::lock_guard<std::mutex> lock(g_mutex);
                
                // Main view showing summary
                // Use Unicode degree symbol (U+00B0) followed by 'C'
                ss << L"CPU: " << static_cast<int>(g_metrics.cpuUsage) << L"% (" << static_cast<int>(g_metrics.cpuTemp) << L"\u00B0C)" << std::endl;
                ss << L"RAM: " << static_cast<int>(g_metrics.memoryUsage) << L"%" << std::endl;
                ss << L"GPU: " << static_cast<int>(g_metrics.gpuUsage) << L"% (" << static_cast<int>(g_metrics.gpuTemp) << L"\u00B0C)" << std::endl;
                ss << L"DISK: " << static_cast<int>(g_metrics.diskUsage) << L"%";
            }
            
            std::wstring text = ss.str();
            RECT textRect = rc;
            textRect.left += 10;
            textRect.top += 10;
            DrawTextW(memDC, text.c_str(), -1, &textRect, DT_NOCLIP);
            
            // Update component rectangles for hover detection
            g_cpuRect = {10, 10, rc.right - 10, 30};
            g_ramRect = {10, 30, rc.right - 10, 50};
            g_gpuRect = {10, 50, rc.right - 10, 70};
            g_diskRect = {10, 70, rc.right - 10, 90};
            
            // Draw resize icon
            POINT pts[3];
            pts[0].x = rc.right - 10;
            pts[0].y = rc.bottom;
            pts[1].x = rc.right;
            pts[1].y = rc.bottom - 10;
            pts[2].x = rc.right;
            pts[2].y = rc.bottom;
            
            HPEN hPen = CreatePen(PS_SOLID, 1, RGB(200, 200, 200));
            HPEN oldPen = (HPEN)SelectObject(memDC, hPen);
            HBRUSH hResizeBrush = CreateSolidBrush(RGB(200, 200, 200));
            HBRUSH oldBrush = (HBRUSH)SelectObject(memDC, hResizeBrush);
            
            Polygon(memDC, pts, 3);
            
            SelectObject(memDC, oldPen);
            DeleteObject(hPen);
            SelectObject(memDC, oldBrush);
            DeleteObject(hResizeBrush);
            
            // Copy from memory DC to screen DC
            BitBlt(hdc, 0, 0, rc.right, rc.bottom, memDC, 0, 0, SRCCOPY);
            
            // Clean up
            SelectObject(memDC, oldFont);
            DeleteObject(hFont);
            SelectObject(memDC, oldBitmap);
            DeleteObject(memBitmap);
            DeleteDC(memDC);
            
            EndPaint(hwnd, &ps);
            return 0;
        }
            
        case WM_LBUTTONDOWN: {
            int xPos = LOWORD(lParam);
            int yPos = HIWORD(lParam);
            
            if (IsInResizeArea(xPos, yPos)) {
                // Start resizing
                g_bResizing = true;
                g_ptResizeStart.x = xPos;
                g_ptResizeStart.y = yPos;
                GetWindowRect(hwnd, &g_rcResizeStart);
                SetCapture(hwnd);
            } else {
                // Start dragging the main window
                g_bDragging = true;
                g_ptDragStart.x = xPos;
                g_ptDragStart.y = yPos;
                SetCapture(hwnd);
            }
            return 0;
        }
            
        case WM_LBUTTONUP: {
            // Stop dragging or resizing
            g_bDragging = false;
            g_bResizing = false;
            ReleaseCapture();
            return 0;
        }
            
        case WM_MOUSEMOVE: {
            int xPos = LOWORD(lParam);
            int yPos = HIWORD(lParam);
            
            // Update mouse cursor
            if (IsInResizeArea(xPos, yPos)) {
                SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
            } else {
                SetCursor(LoadCursor(NULL, IDC_ARROW));
            }
            
            if (g_bResizing) {
                // Calculate new window size
                int newWidth = g_rcResizeStart.right - g_rcResizeStart.left + (xPos - g_ptResizeStart.x);
                int newHeight = g_rcResizeStart.bottom - g_rcResizeStart.top + (yPos - g_ptResizeStart.y);
                
                // Limit minimum size
                if (newWidth < 100) newWidth = 100;
                if (newHeight < 60) newHeight = 60;
                
                // Update window size
                g_windowWidth = newWidth;
                g_windowHeight = newHeight;
                UpdateWindowSize();
                
                // Force redraw
                InvalidateRect(hwnd, NULL, TRUE);
            } else if (g_bDragging) {
                // Calculate new position
                RECT rc;
                GetWindowRect(hwnd, &rc);
                
                int newX = rc.left + (xPos - g_ptDragStart.x);
                int newY = rc.top + (yPos - g_ptDragStart.y);
                
                // Move window
                SetWindowPos(hwnd, NULL, newX, newY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
            } else {
                // Check for hovering over components
                DetailViewMode newMode = NONE;
                
                if (IsPointInRect(xPos, yPos, g_cpuRect)) {
                    newMode = CPU_DETAILS;
                } else if (IsPointInRect(xPos, yPos, g_gpuRect)) {
                    newMode = GPU_DETAILS;
                } else if (IsPointInRect(xPos, yPos, g_diskRect)) {
                    newMode = DISK_DETAILS;
                }
                
                // If hovering over a component, show detail window
                if (newMode != NONE) {
                    if (g_detailViewMode != newMode || !g_detailWindow) {
                        // Get screen coordinates for the detail window
                        POINT pt = {xPos, yPos};
                        ClientToScreen(hwnd, &pt);
                        
                        // Show detail window below the component
                        ShowDetailWindow(newMode, pt.x, pt.y + 20);
                    }
                } else if (g_detailWindow) {
                    // If not hovering over any component, close the detail window
                    DestroyWindow(g_detailWindow);
                    g_detailWindow = NULL;
                    g_detailViewMode = NONE;
                }
                
                // Enable mouse tracking if not already enabled
                if (!g_bMouseTracking) {
                    TRACKMOUSEEVENT tme;
                    tme.cbSize = sizeof(TRACKMOUSEEVENT);
                    tme.dwFlags = TME_LEAVE;
                    tme.hwndTrack = hwnd;
                    tme.dwHoverTime = HOVER_DEFAULT;
                    TrackMouseEvent(&tme);
                    g_bMouseTracking = true;
                }
            }
            return 0;
        }
            
        case WM_MOUSELEAVE: {
            // Mouse left the window, close detail window if it exists
            if (g_detailWindow) {
                DestroyWindow(g_detailWindow);
                g_detailWindow = NULL;
                g_detailViewMode = NONE;
            }
            
            g_bMouseTracking = false;
            return 0;
        }
            
        case WM_KEYDOWN: {
            // Handle keyboard shortcuts
            switch (wParam) {
                case VK_ESCAPE:
                    // Exit application on ESC key
                    DestroyWindow(hwnd);
                    break;
                    
                case VK_UP:
                    // Increase opacity
                    g_opacity = min(255, g_opacity + 10);
                    UpdateWindowOpacity();
                    break;
                    
                case VK_DOWN:
                    // Decrease opacity
                    g_opacity = max(50, g_opacity - 10);
                    UpdateWindowOpacity();
                    break;
                    
                case VK_ADD:
                case VK_OEM_PLUS:
                    // Increase font size
                    g_fontSize = min(48, g_fontSize + 2);
                    InvalidateRect(hwnd, NULL, TRUE);
                    break;
                    
                case VK_SUBTRACT:
                case VK_OEM_MINUS:
                    // Decrease font size
                    g_fontSize = max(8, g_fontSize - 2);
                    InvalidateRect(hwnd, NULL, TRUE);
                    break;
                    
                case 'A':
                    // Toggle auto font scaling
                    g_bAutoScaleFont = !g_bAutoScaleFont;
                    InvalidateRect(hwnd, NULL, TRUE);
                    break;
                    
                case 'H':
                    // Toggle visibility
                    g_bHidden = !g_bHidden;
                    ShowWindow(hwnd, g_bHidden ? SW_HIDE : SW_SHOW);
                    break;
            }
            return 0;
        }
            
        case WM_RBUTTONUP: {
            // Show context menu
            POINT pt;
            pt.x = LOWORD(lParam);
            pt.y = HIWORD(lParam);
            ClientToScreen(hwnd, &pt);
            
            HMENU hMenu = CreatePopupMenu();
            
            // Add font size submenu
            HMENU hFontSizeMenu = CreatePopupMenu();
            AppendMenu(hFontSizeMenu, MF_STRING | (g_fontSize == 16 ? MF_CHECKED : MF_UNCHECKED), 101, "Small (16)");
            AppendMenu(hFontSizeMenu, MF_STRING | (g_fontSize == 20 ? MF_CHECKED : MF_UNCHECKED), 102, "Medium (20)");
            AppendMenu(hFontSizeMenu, MF_STRING | (g_fontSize == 24 ? MF_CHECKED : MF_UNCHECKED), 103, "Large (24)");
            AppendMenu(hFontSizeMenu, MF_STRING | (g_fontSize == 28 ? MF_CHECKED : MF_UNCHECKED), 104, "Extra Large (28)");
            AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFontSizeMenu, "Font Size");
            
            // Add auto scale font option
            AppendMenu(hMenu, MF_STRING | (g_bAutoScaleFont ? MF_CHECKED : MF_UNCHECKED), 105, "Auto Scale Font");
            
            // Add opacity submenu
            HMENU hOpacityMenu = CreatePopupMenu();
            AppendMenu(hOpacityMenu, MF_STRING | (g_opacity == 255 ? MF_CHECKED : MF_UNCHECKED), 201, "Opaque (100%)");
            AppendMenu(hOpacityMenu, MF_STRING | (g_opacity == 200 ? MF_CHECKED : MF_UNCHECKED), 202, "Light Transparent (80%)");
            AppendMenu(hOpacityMenu, MF_STRING | (g_opacity == 150 ? MF_CHECKED : MF_UNCHECKED), 203, "Medium Transparent (60%)");
            AppendMenu(hOpacityMenu, MF_STRING | (g_opacity == 100 ? MF_CHECKED : MF_UNCHECKED), 204, "High Transparent (40%)");
            AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hOpacityMenu, "Opacity");
            
            // Add other menu items
            AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
            AppendMenu(hMenu, MF_STRING, 1, g_bHidden ? "Show" : "Hide");
            AppendMenu(hMenu, MF_STRING, 2, "Exit");
            
            TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
            DestroyMenu(hMenu);
            return 0;
        }
            
        case WM_COMMAND: {
            switch (LOWORD(wParam)) {
                case 1: // Hide/Show
                    g_bHidden = !g_bHidden;
                    ShowWindow(hwnd, g_bHidden ? SW_HIDE : SW_SHOW);
                    return 0;
                    
                case 2: // Exit
                    DestroyWindow(hwnd);
                    return 0;
                    
                case 101: // Small font
                    g_fontSize = 16;
                    InvalidateRect(hwnd, NULL, TRUE);
                    return 0;
                    
                case 102: // Medium font
                    g_fontSize = 20;
                    InvalidateRect(hwnd, NULL, TRUE);
                    return 0;
                    
                case 103: // Large font
                    g_fontSize = 24;
                    InvalidateRect(hwnd, NULL, TRUE);
                    return 0;
                    
                case 104: // Extra large font
                    g_fontSize = 28;
                    InvalidateRect(hwnd, NULL, TRUE);
                    return 0;
                    
                case 105: // Toggle auto scale font
                    g_bAutoScaleFont = !g_bAutoScaleFont;
                    InvalidateRect(hwnd, NULL, TRUE);
                    return 0;
                    
                case 201: // Opaque
                    g_opacity = 255;
                    UpdateWindowOpacity();
                    return 0;
                    
                case 202: // Light transparent
                    g_opacity = 200;
                    UpdateWindowOpacity();
                    return 0;
                    
                case 203: // Medium transparent
                    g_opacity = 150;
                    UpdateWindowOpacity();
                    return 0;
                    
                case 204: // High transparent
                    g_opacity = 100;
                    UpdateWindowOpacity();
                    return 0;
            }
            return 0;
        }
            
        case WM_USER + 1: {
            // System tray icon message
            if (lParam == WM_LBUTTONDOWN) {
                // Toggle visibility on tray icon click
                g_bHidden = !g_bHidden;
                ShowWindow(hwnd, g_bHidden ? SW_HIDE : SW_SHOW);
            } else if (lParam == WM_RBUTTONUP) {
                // Show context menu for system tray icon
                POINT pt;
                GetCursorPos(&pt);
                
                HMENU hMenu = CreatePopupMenu();
                AppendMenu(hMenu, MF_STRING, 1, g_bHidden ? "Show" : "Hide");
                AppendMenu(hMenu, MF_STRING, 2, "Exit");
                
                SetForegroundWindow(hwnd);
                TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
                DestroyMenu(hMenu);
            }
            return 0;
        }
            
        case WM_DESTROY: {
            // Remove system tray icon
            NOTIFYICONDATA nid = {0};
            nid.cbSize = sizeof(NOTIFYICONDATA);
            nid.hWnd = hwnd;
            nid.uID = 1;
            Shell_NotifyIcon(NIM_DELETE, &nid);
            
            // Stop metrics update thread
            g_bRunning = false;
            g_cv.notify_all();
            
            // Clean up PDH queries
            PdhCloseQuery(cpuQuery);
            PdhCloseQuery(diskQuery);
            
            // Destroy detail window if exists
            if (g_detailWindow) {
                DestroyWindow(g_detailWindow);
                g_detailWindow = NULL;
            }
            
            PostQuitMessage(0);
            return 0;
        }
            
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // Register window class
    WNDCLASSEX wcex = {0};
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = hInstance;
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszClassName = "SystemMonitorClass";
    
    if (!RegisterClassEx(&wcex)) {
        MessageBox(NULL, "Window Registration Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
        return 1;
    }
    
    // Create window
    g_hwnd = CreateWindowEx(
        WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, // Extended window style
        "SystemMonitorClass",                             // Window class
        "System Monitor",                                 // Window title
        WS_POPUP,                                         // Window style
        100, 100,                                         // Position
        g_windowWidth, g_windowHeight,                    // Size
        NULL, NULL, hInstance, NULL
    );
    
    if (!g_hwnd) {
        MessageBox(NULL, "Window Creation Failed!", "Error", MB_ICONEXCLAMATION | MB_OK);
        return 1;
    }
    
    // Set window transparency
    UpdateWindowOpacity();
    
    // Show window
    ShowWindow(g_hwnd, nCmdShow);
    UpdateWindow(g_hwnd);
    
    // Message loop
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        
        // Force redraw every second to update metrics
        static DWORD lastUpdate = 0;
        DWORD currentTime = GetTickCount();
        if (currentTime - lastUpdate > 1000) {
            InvalidateRect(g_hwnd, NULL, TRUE);
            lastUpdate = currentTime;
        }
    }
    
    return (int)msg.wParam;
}
